import { Injectable, BadRequestException, SetMetadata, Request } from '@nestjs/common';
import { BaseDao } from '@/common/baseDao/base.service'
import { Util } from '@/common/util/util.service'
import { UserDto } from './user.dto';
import { InsertOneResult } from 'mongodb'
import * as bcrypt from 'bcryptjs';
import Config from '@/config'
import { JwtService } from '@/common/jwt/jwt.service'


@Injectable()
export class AuthService {
    constructor(
        private baseDao: BaseDao, private util: Util,
        private jwtService: JwtService
    ) { }
    async register(userDto: UserDto): Promise<any> {
        const { username, password } = userDto;
        const key = Config.passwordSecret; // 从配置中获取密钥
        const hashedPassword = await this.hashPassword(password, key);
        // 检查用户名是否已存在
        const existingUser = await this.baseDao.findByWhereJson({
            dbName: "quick-users",
            whereJson: {
                username,
            }
        })
        if (existingUser) {
            throw new BadRequestException('用户名已存在');
        }
        const userInfo: InsertOneResult = await this.baseDao.add({
            dbName: "quick-users",
            dataJson: {
                username: username,
                password: hashedPassword,
                role: ['admin']
            }
        })

        const { insertedId } = userInfo;
        const token = await this.jwtService.generateToken(insertedId.toHexString());
        const expired = await this.jwtService.getExpired(token);
        return {
            token,
            expired
        }
    }

    private async hashPassword(password: string, key: string): Promise<string> {
        const hashedPassword = await bcrypt.hash(password + key, 10); // 使用密钥加密密码
        return hashedPassword;
    }

    async login(userDto: UserDto): Promise<any> {
        const { username, password } = userDto;
        console.log('userDto', userDto)
        const userInfo = await this.baseDao.findByWhereJson({
            dbName: "quick-users",
            whereJson: {
                username,
            }
        })


        if (!userInfo) {
            // return this.util.errors("账号或密码错误");
            throw new BadRequestException('账号或密码错误');
        }

        const key = Config.passwordSecret; // 从配置中获取密钥
        const isMatch = await bcrypt.compare(password + key, userInfo.password); // 使用密钥解密密码
        if (!isMatch) {
            // return this.util.errors("")
            throw new BadRequestException('账号或密码错误');
        }
        return {
            token: await this.jwtService.generateToken(userInfo._id.toHexString()),
            expired: await this.jwtService.getExpired(await this.jwtService.generateToken(userInfo._id.toHexString())),
            ...this.util.filterObject(userInfo, ['password'], false)
        }
    }
    // 联表查询
    async selects(): Promise<any> {
        return await this.baseDao.selects({
            dbName: 'quick-users',
            whereJson: {
                username: 'agent'
            },
            fieldJson: {

            },
            foreignDB: [
                {
                    dbName: "quick-roles", // 副表名
                    localKey: "role", // 主表外键字段名
                    foreignKey: "role_id", // 副表外键字段名
                    as: "user_roles",  //副表as字段
                    // 副表where条件
                    whereJson: {
                        // role_id:'admin'
                    },
                    // // 副表字段显示规则
                    fieldJson: {
                        // comment:true  
                        // permission:true
                    },
                    // // 副表排序规则
                    sortArr: [{ "name": "_add_time", "type": "desc" }]
                },
                {
                    dbName: "quick-permissions", // 副表名
                    localKey: "user_roles.permission", // 主表外键字段名
                    // limit:1,
                    foreignKey: "permission_id", // 副表外键字段名
                    as: "user_permissions",  //副表as字段
                    limit: 1,
                    sortArr: [{ "name": "sort", "type": "asc" }],
                    fieldJson: {
                        // url:true
                    }
                }
            ]
        })
    }

    // 获取身份菜单
    async getMenu(req): Promise<any> {
        const { _ } = this.util;
        const { menus, userInfo } = req;
        let whereJson = {}
        if (!userInfo.role.includes(Config['sysIdentifier'])) {
            whereJson = {
                menu_id: _.in(menus)
            }
        }

        const res = await this.baseDao.selects({
            dbName: 'quick-menus',
            whereJson,
        })
        let treeProps = {
            id: "menu_id",
            parent_id: "parent_id",
            children: "children"
        };
        return {
            ...res,
            menus: this.util.buildTree(res['rows'], treeProps)
        }
    }
}